package org.example.chinesedays.utils;

import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.chinesedays.entity.dto.DateRangeDTO;
import org.example.chinesedays.entity.po.ChineseDay;
import org.example.chinesedays.service.IChineseDayService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.example.chinesedays.utils.HolidayFetcher.fetchHoliday;

@Slf4j
@Component
@RequiredArgsConstructor
public class getDaysAndWriteFile {

    private final IChineseDayService chineseDayService;
    @Transactional
    public void getDays(int year) throws IOException, InterruptedException {
        // 获取节假日数据
        String result = fetchHoliday(year);
        if (result.isEmpty()) {
            log.warn("未获取到{}年的节假日数据", year);
            return;
        }

        // 解析年份
        int extractedYear = HolidayParser.extractYear(result);
        // 查询该年份已有的节假日数据
        List<ChineseDay> list = chineseDayService.lambdaQuery()
                .eq(ChineseDay::getYear, extractedYear)
                .list();

        if (list == null) {
            log.error("查询数据库失败，返回结果为null，年份: {}", extractedYear);
            return;
        }

        // 解析节假日和调休工作日数据
        List<DateRangeDTO> holidays = HolidayParser.parseHolidays(result);
        List<DateRangeDTO> adjustedWorkdays = HolidayParser.parseAdjustedWorkdays(result);

        // 构建节假日map
        Map<LocalDate, String> holidayMap = new HashMap<>();
        for (DateRangeDTO dateRange : holidays) {
            for (LocalDate date = dateRange.getStart(); !date.isAfter(dateRange.getEnd()); date = date.plusDays(1)) {
                holidayMap.put(date, dateRange.getName());
            }
        }

        // 构建调休上班日map
        Map<LocalDate, String> adjustedWorkdayMap = adjustedWorkdays.stream()
                .collect(Collectors.toMap(DateRangeDTO::getStart, DateRangeDTO::getName));

        // 生成全年日期范围
        LocalDate start = LocalDate.of(extractedYear, 1, 1);
        LocalDate end = LocalDate.of(extractedYear, 12, 31);

        // 如果数据库中没有数据，初始化全年日期数据
        if (list.isEmpty()) {
            insertData(extractedYear, start, end, holidayMap, adjustedWorkdayMap);
        }

//        updateData(list, holidayMap, adjustedWorkdayMap, extractedYear);
    }

    private void updateData(List<ChineseDay> list, Map<LocalDate, String> holidayMap, Map<LocalDate, String> adjustedWorkdayMap, int extractedYear) {
        // 已有数据，只更新节假日和调休数据
        List<ChineseDay> updatedList = new ArrayList<>();
        for (ChineseDay chineseDay : list) {
            LocalDate date = chineseDay.getDate();

            if (holidayMap.containsKey(date)) {
                ChineseDay updated = BeanUtil.copyProperties(chineseDay, ChineseDay.class);
                updated.setRemark(holidayMap.get(date));
                updated.setWorkFlag(false);
                updatedList.add(updated);
            }

            if (adjustedWorkdayMap.containsKey(date)) {
                ChineseDay updated = BeanUtil.copyProperties(chineseDay, ChineseDay.class);
                updated.setRemark(adjustedWorkdayMap.get(date));
                updated.setWorkFlag(true);
                updatedList.add(updated);
            }
        }

        if (!updatedList.isEmpty()) {
            chineseDayService.updateBatchById(updatedList);
            log.info("更新 {} 年的节假日/调休数据，共更新 {} 条记录", extractedYear, updatedList.size());
        } else {
            log.info("{} 年无需更新的节假日/调休数据", extractedYear);
        }
    }

    private void insertData(int extractedYear, LocalDate start, LocalDate end, Map<LocalDate, String> holidayMap, Map<LocalDate, String> adjustedWorkdayMap) {
        log.info("数据库中暂无 {} 年数据，开始初始化", extractedYear);
        List<ChineseDay> initList = new ArrayList<>();
        for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) {
            ChineseDay chineseDay = new ChineseDay();
            chineseDay.setYear(String.valueOf(extractedYear));
            chineseDay.setDate(date);

            // 默认是工作日
            chineseDay.setWorkFlag(true);
            chineseDay.setRemark("正常上班");

            // 如果是周末，设为非工作日
            if (date.getDayOfWeek() == DayOfWeek.SATURDAY || date.getDayOfWeek() == DayOfWeek.SUNDAY) {
                chineseDay.setWorkFlag(false);
                chineseDay.setRemark("周末");
            }

            // 如果是法定节假日，覆盖设置为非工作日
            if (holidayMap.containsKey(date)) {
                chineseDay.setWorkFlag(false);
                chineseDay.setRemark(holidayMap.get(date));
            }

            // 如果是调休工作日，覆盖设置为工作日
            if (adjustedWorkdayMap.containsKey(date)) {
                chineseDay.setWorkFlag(true);
                chineseDay.setRemark(adjustedWorkdayMap.get(date));
            }

            initList.add(chineseDay);
        }

        chineseDayService.saveBatch(initList);
        log.info("{} 年节假日数据初始化完成，共保存 {} 条记录", extractedYear, initList.size());
    }

}
